﻿using System;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class DM11Visitor:MonoBehaviour
{
    void Start()
    {
        
        DMShapeContainer container = new DMShapeContainer();

        DMShpere shpere1 = new DMShpere();
        container.AddShape(shpere1);
        DMCylinder cylinder1 = new DMCylinder();
        container.AddShape(cylinder1);
        DMCube cube1 = new DMCube();
        container.AddShape(cube1);
        DMCube cube2 = new DMCube();
        container.AddShape(cube2);

        // 计数访问  amountVisitor
        AmountVisitor amountVisitor= new AmountVisitor();
        // xxVisitor 类似于一个类型的访问任务对象, 而 amountVisitor 对象就是一个个数访问任务
        // amountVisitor 对象有一个 amount 属性，用于记录图形的总数( xx属性, 用于记录此类业务结果的数据值 )
        // amountVisitor 对象有几个方法，每个对应一种不同的类型的访问，并在访问时更新 amount 属性的值
        container.RunVisitor(amountVisitor); //!=把任务访问对象传递到每一个被访问者对象内部,任务访问对象在被访问者对象内部执行访问任务可以记录很多数据,因为在同一上下文环境
        int amount = amountVisitor.amount;
        Debug.Log("图形总数：" + amount);

        // CubeAmountVisitor cubeAmountVisitor = new CubeAmountVisitor();
        // container.RunVisitor(cubeAmountVisitor);
        // int cubeAmount = cubeAmountVisitor.amount;
        // Debug.Log("Cube总数:" + cubeAmount);


        // EdgeVisitor edgeVisitor = new EdgeVisitor();
        // container.RunVisitor(edgeVisitor);
        // int edgeAmount = edgeVisitor.amount;
        // Debug.Log("边总数:" + edgeAmount);


    }
}

class DMShapeContainer
{
    // 存储将要被访问的人
    private List<IDMShape> mShapes = new List<IDMShape>();
    public void AddShape(IDMShape shape)
    {
        mShapes.Add(shape);
    }
    
    public void RunVisitor(IShapeVisitor visitor)
    {
        // 遍历要被访问的人
        foreach (IDMShape shape in mShapes)
        {
            shape.RunVisitor(visitor); // 传递下去的效果是怎么达到的,怎么运转的??
        }
    }
}

abstract class IShapeVisitor
{
    // 访问已知的所有的形状,新的形状要加进来
    public abstract void VisitSphere(DMShpere sphere);
    public abstract void VisitCylinder(DMCylinder cylinder);
    public abstract void VisitCube(DMCube cube);
}

class AmountVisitor:IShapeVisitor {
    public int amount = 0;
    // 访问每一种形状的方法,访问完将 amount 加1, 业务!
    public override void VisitSphere(DMShpere sphere)
    {
        amount++;
    }

    public override void VisitCylinder(DMCylinder cylinder)
    {
        amount++;
    }

    public override void VisitCube(DMCube cube)
    {
        amount++;
    }
}

class CubeAmountVisitor : IShapeVisitor
{
    public int amount = 0;
    public override void VisitSphere(DMShpere sphere)
    {
        return;
    }

    public override void VisitCylinder(DMCylinder cylinder)
    {
        return;
    }

    public override void VisitCube(DMCube cube)
    {
        amount++;
    }
}
class EdgeVisitor : IShapeVisitor
{
    public int amount = 0;
    public override void VisitSphere(DMShpere sphere)
    {
        amount += 1;
    }

    public override void VisitCylinder(DMCylinder cylinder)
    {
        amount += 2;
    }

    public override void VisitCube(DMCube cube)
    {
        amount += 12;
    }
}

abstract class IDMShape{
    //public abstract int GetVolume();
    public abstract void RunVisitor( IShapeVisitor visitor );
}
class DMShpere : IDMShape
{
    //public override int GetVolume()
    //{
    //    return 30;
    //}

    public override void RunVisitor(IShapeVisitor visitor)
    {
        visitor.VisitSphere(this);
    }
}
class DMCylinder : IDMShape
{
    //public override int GetVolume()
    //{
    //    return 20;
    //}
    public override void RunVisitor(IShapeVisitor visitor)
    {
        visitor.VisitCylinder(this);
    }
}
class DMCube : IDMShape
{
    //public override int GetVolume()
    //{
    //    return 10;
    //}
    public override void RunVisitor(IShapeVisitor visitor)
    {
        visitor.VisitCube(this);
    }
}

